layui.define(['layer'], function (exports) {
    /**
     * 封装的AJAX请求工具，支持请求拦截和响应拦截
     */
    const request = {
        // 默认配置
        defaults: {
            baseUrl: '',
            timeout: 10000,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        },
        // 将对象转换为 x-www-form-urlencoded 格式的字符串
        convertToFormData: (params) => {
            if (!params) return '';
            return Object.entries(params)
                .map(([key, value]) => {
                    // 处理数组参数，例如 { ids: [1, 2] } 转换为 ids=1&ids=2
                    if (Array.isArray(value)) {
                        return value.map(v => `${encodeURIComponent(key)}=${encodeURIComponent(v)}`).join('&');
                    }
                    return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
                })
                .join('&');
        },

        // 请求拦截器
        requestInterceptors: [],

        // 响应拦截器
        responseInterceptors: [
            // 默认的响应拦截器，处理错误情况
            (response) => {
                if (!response.ok) {
                    layer.msg('请求服务失败: ' + response.status, {icon: 2})
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                return response;
            },
            // 处理JSON解析
            async (response) => {
                const contentType = response.headers.get('content-type');
                if (contentType && contentType.includes('application/json')) {
                    const json = await response.json()
                    if (json.code === 200) {
                        return json;
                    } else if (json.code === 401) {
                        if (!window.location.pathname.startsWith('/page/login.html')) {// 如果在登录界面时不跳转
                            window.location.href = '/page/login.html?redirect=' + window.location.pathname
                        }
                        layer.msg('登录已失效，请重新登录', {icon: 2})
                    } else if (json.msg) {
                        layer.msg(json.msg, {icon: 2})
                    }
                    throw new Error(json);
                }
                return await response.text();
            }
        ],

        // 错误处理器
        errorHandler: (error) => {
            // 这里可以添加统一的错误提示，例如使用弹窗组件
            // console.error('Request error:', error.message);
            // alert(`请求出错: ${error.message}`);
            throw error; // 继续抛出错误，以便调用者可以选择进一步处理
        },

        /**
         * 发送AJAX请求
         * @param {Object} options - 请求配置
         * @param {string} options.url - 请求URL
         * @param {string} [options.method='GET'] - 请求方法
         * @param {Object} [options.data] - 请求数据
         * @param {Object} [options.headers] - 请求头
         * @param {number} [options.timeout] - 超时时间
         * @returns {Promise<any>} - 响应数据
         */
        async request(options) {
            // 合并默认配置
            const config = {
                ...this.defaults,
                ...options,
                headers: {
                    ...this.defaults.headers,
                    ...options.headers
                }
            };

            // 应用请求拦截器
            let interceptedConfig = {...config};
            for (const interceptor of this.requestInterceptors) {
                interceptedConfig = await interceptor(interceptedConfig);
            }

            // 构建请求URL
            const fullUrl = interceptedConfig.baseUrl + interceptedConfig.url;

            // 构建fetch选项
            const fetchOptions = {
                method: interceptedConfig.method || 'GET',
                headers: interceptedConfig.headers,
                timeout: interceptedConfig.timeout
            };

            // 添加请求体
            if (interceptedConfig.data) {
                if (fetchOptions.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
                    fetchOptions.body = this.convertToFormData(interceptedConfig.data)
                } else if (fetchOptions.headers['Content-Type'] === 'application/json') {
                    fetchOptions.body = JSON.stringify(interceptedConfig.data);
                } else {
                    fetchOptions.body = interceptedConfig.data;
                }
            }
            try {
                // 发送请求
                let response = await fetch(fullUrl, fetchOptions);
                // 应用响应拦截器
                for (const interceptor of this.responseInterceptors) {
                    response = await interceptor(response);
                }
                return response;
            } catch (error) {
                // 应用错误处理器
                return this.errorHandler(error);
            }
        },
        // 快捷方法
        get(url, options = {}) {
            return this.request({...options, url, method: 'GET'});
        },
        post(url, data, options = {}) {
            return this.request({...options, url, method: 'POST', data});
        },
        put(url, data, options = {}) {
            return this.request({...options, url, method: 'PUT', data});
        },
        delete(url, data, options = {}) {
            return this.request({...options, url, method: 'DELETE', data});
        }
    };
    // 输出模块接口
    exports('request', request);
});

